#ifndef DCE6_H
#define DCE6_H
/*
  author Sylvain Bertrand <sylvain.bertrand@gmail.com>
  Protected by linux GNU GPLv2
  Copyright 2012-2014
*/

#ifdef __MOD_C__
struct class *class;
DEFINE_IDA(ida);
#else
extern struct class *class;
extern struct ida ida;
#endif

static const u32 width_max = 16384;
static const u32 height_max = 16384;

/* 100000 us = 100 ms */	
#define USEC_TIMEOUT 100000

/* page flipping only */
struct crtc_surfs {
	u64 primary;
	u64 secondary;
};

#define PF_STATE_NONE		0
#define PF_STATE_NOT_SUBMITED	1
#define PF_STATE_SUBMITED	2
struct pf {
	struct crtc_surfs crtc_surfs;
	/* this function will run in irq hard context */
	spinlock_t lock;
	void (*notify)(u8 i, u32 v_blanks_n, struct timespec monotonic_raw_tp,
								void *data);
	void *data;
};

struct dp {
	struct dce6 *dce;			/* to navigate back to dce */	
	u8 i;

	u8 active;

	u8 edp;
	u8 atb_dfp;

	u8 atb_aux_i2c_id;
	struct i2c_adapter i2c_adapter;
	void *edid;				/* NULL is not fatal */
	u16 edid_sz;

	u8 lanes_n;
	u8 link_rate;
	u8 trans_link_rate_max;

	u8 connected;
	u8 hpd;					/* no hpd->0xff */	

	u8 dpcd_info[8];			/* see dp specs */

	struct pf pf;

	/* for sysfs */
	struct device d;
	unsigned id;
};

struct irq {
	spinlock_t hpds_lock;
	u8 hpds;/* protected by above spinlock */
	/* avoid child device registration after suspend "prepare" call */
	u8 hpd_dev_registration_lock;/* protected by the dce mutex */
};

struct dce6 {
	struct mutex mutex;

	/* carefull: hpd index may not be crtc index */
	u8 hpds_used;
	u8 dps_used;
	struct dp dps[CRTCS_N_MAX];

	struct dce6_dev ddev;

	struct irq irq;

	/* sysfs */
	struct device *parent_char_dev;	
};

static inline void lock(struct dce6 *dce)
{
	mutex_lock(&dce->mutex);
}

static inline void unlock(struct dce6 *dce)
{
	mutex_unlock(&dce->mutex);
}
long dp_dpm_off(struct dce6 *dce, u8 i);
#endif
